package com.heima.comment.service.Impl;

import com.heima.comment.dtos.CommentDto;
import com.heima.comment.dtos.CommentLikeDto;
import com.heima.comment.dtos.CommentSaveDto;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.comment.vo.ApCommentVo;
import com.heima.feigns.user.UserFeign;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.stream.Collectors;


@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    UserFeign userFeign;

    @Autowired
    MongoTemplate mongoTemplate;


    /**
     * 根据文章id查询评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findByArticleId(CommentDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        Integer size = dto.getSize();
        if (size==null||size<=0){
            dto.setSize(10);
        }
        dto.setSize(Math.min(dto.getSize(),50));


        List<ApComment> commentList = null;

        //判断是否首页热点评论
        if (dto.getIndex().intValue()==1){

            //为首页,查询热点评论
        commentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
                .and("type").is(0)
                .and("flag").is(1)
        ).with(Sort.by(Sort.Order.desc("likes"))),ApComment.class);
            int hotSize = commentList.size();
            //查询Mongo文章所有评论列表,size为减去热点评论的size
        List<ApComment> apCommentList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("type").is(0)
                        .and("flag").is(0)
                        .and("createdTime").lt(dto.getMinDate())
                ).limit(dto.getSize()-hotSize).with(Sort.by(Sort.Direction.DESC, "createdTime"))
                , ApComment.class
        );
        //合并评论,因为两个评论flag互斥
            commentList.addAll(apCommentList);
        }else{
            commentList = mongoTemplate.find(
                    Query.query(Criteria
                            .where("entryId").is(dto.getArticleId())
                            .and("type").is(0)
                            .and("flag").is(0)
                            .and("createdTime").lt(dto.getMinDate()))
                            .limit(dto.getSize())
                            .with(Sort.by(Sort.Order.desc("createdTime"))),
                    ApComment.class);
        }

        //如果用户未登录,直接返回频道列表
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.okResult(commentList);
        }
        //远程调用查询用户信息未登录 直接返回评论列表
        //todo ????why  上面不是已经判了吗
        ApUser apUser = userFeign.findUserById(user.getId().longValue());
        if (apUser == null) {
            return ResponseResult.okResult(commentList);
        }
        //用户登录,加载当前用户对评论点赞的列表
        List<ApCommentVo> apCommentVoList = new ArrayList<>();

        //获取当前文章对应的所有评论id列表
        List<String> idList = commentList.stream().map(x -> x.getId()).collect(Collectors.toList());

        //查询点赞列表,按照评论id筛选
        List<ApCommentLike> apCommentLikeList = mongoTemplate.find(Query.query(Criteria.where("commentId").in(idList).and("operation").is(0).and("authorId").is(user.getId())), ApCommentLike.class);


        //保存用户回显点赞数据集合
        // 遍历当前用户点赞列表 和当前评论列表
        if (commentList!=null&&commentList.size()>0&&apCommentLikeList!=null&&apCommentLikeList.size()>0){
            //遍历评论列表
            commentList.forEach(x->{
                ApCommentVo apCommentVo = new ApCommentVo();
                try {
                    BeanUtils.copyProperties(x,apCommentVo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //处理回显问题
                apCommentLikeList.forEach(apCommentLike -> {
                    if (x.getId().equals(apCommentLike.getCommentId())){
                        apCommentVo.setOperation((short) 0);
                    }
                });
                apCommentVoList.add(apCommentVo);
            });

            return ResponseResult.okResult(apCommentVoList);
        }

        return ResponseResult.okResult(commentList);
    }

    @Autowired
    CommentHotService commentHotService;

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //参数校验
        if (dto==null||dto.getCommentId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //获取登录用户
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //查询当前评论是否存在
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"评论不存在");
        }
        //查询评论的点赞是否已经存在
        ApCommentLike apCommentLike = mongoTemplate.findOne(Query.query(Criteria.where("authorId").is(user.getId())
                .and("commentId").is(dto.getCommentId())
        ), ApCommentLike.class);

        if (apCommentLike!=null&&dto.getOperation().intValue()==0&&apCommentLike.getOperation().intValue()==0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"无需重复点赞");
        }
        //不存在,就点赞
        if (dto.getOperation().intValue() == 0) {
            if (apCommentLike == null) {
                 apCommentLike = new ApCommentLike();
                 apCommentLike.setAuthorId(user.getId());
                 apCommentLike.setCommentId(apComment.getId());
            }
            apCommentLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentLike);
            //保存点赞数
            apComment.setLikes(apComment.getLikes()+1);
            mongoTemplate.save(apComment);

            // 计算热点评论
            if (apComment.getLikes()>=5&&apComment.getFlag().shortValue()==0){
                commentHotService.hotCommentExecutor(apComment.getEntryId(),apComment);
            }
        }else{
            apCommentLike.setOperation((short) 1);
            mongoTemplate.save(apCommentLike);

            //更新点赞数
            apComment.setLikes((apComment.getLikes()-1)<0?0:apComment.getLikes()-1);
            mongoTemplate.save(apComment);
        }
        //返回结果
        //todo 为什么返回map
        Map<String,Object> map = new HashMap<>();
        map.put("likes",apComment.getLikes());
        return ResponseResult.okResult(map);
    }

    /**
     * 保存评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //文本长度限制
        if (dto.getContent().length()>140|| StringUtils.isNotBlank(dto.getContent())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // TODO 内容安全检测
        //获取登录用户
        ApUser apUser = AppThreadLocalUtils.getUser();
        if (apUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        //远程调用查询用户信息
        ApUser userById = userFeign.findUserById(apUser.getId().longValue());

        ApComment apComment = new ApComment();
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setType((short) 0);
        apComment.setAuthorId(userById.getId());
        apComment.setAuthorName(userById.getName());
        apComment.setImage(apUser.getImage());
        apComment.setCreatedTime(new Date());  // 创建时间
        apComment.setUpdatedTime(new Date());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setFlag((short) 0);

        //保存评论
        mongoTemplate.save(apComment);
        //返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
